#!/usr/bin/python
# -*- coding: utf-8 -*-

#Author: Yuanhao Li <jay_21cn@hotmail.com>
#File: ingcrss.py
#Usage: Client of ING from project Babel
#Copyright (C) 2007 Yuanhao Li<jay_21cn@hotmail.com>

#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software Foundation,
#Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#本程序是遵从 GPL 2.0 许可发布的. 你可以自由修改和再发布本程序, 
#但请遵守 GPL 2.0 条款, 尊重知识产权.

import urllib

from PyQt4 import QtCore
from PyQt4.QtCore import QRegExp, QLocale, QDateTime, QString
from PyQt4.QtXml import QXmlSimpleReader, QXmlInputSource, QXmlDefaultHandler

class DefaultHandler(QXmlDefaultHandler):
	def __init__(self, rss):
		QXmlDefaultHandler.__init__(self)
		self.rss = rss
		self.date = QDateTime()
		self.locale = QLocale()

	def _translateDateTimeToLocal(self, dt):
		if dt.contains(QString('Jan')):
			dt.replace(QString('Jan'), self.locale.monthName(1))
		elif dt.contains(QString('Feb')):
			dt.replace(QString('Feb'), self.locale.monthName(2))
		elif dt.contains(QString('Mar')):
			dt.replace(QString('Mar'), self.locale.monthName(3))
		elif dt.contains(QString('Apr')):
			dt.replace(QString('Apr'), self.locale.monthName(4))
		elif dt.contains(QString('May')):
			dt.replace(QString('May'), self.locale.monthName(5))
		elif dt.contains(QString('Jun')):
			dt.replace(QString('Jun'), self.locale.monthName(6))
		elif dt.contains(QString('Jul')):
			dt.replace(QString('Jul'), self.locale.monthName(7))
		elif dt.contains(QString('Aug')):
			dt.replace(QString('Aug'), self.locale.monthName(8))
		elif dt.contains(QString('Sep')):
			dt.replace(QString('Sep'), self.locale.monthName(9))
		elif dt.contains(QString('Oct')):
			dt.replace(QString('Oct'), self.locale.monthName(10))
		elif dt.contains(QString('Nov')):
			dt.replace(QString('Nov'), self.locale.monthName(11))
		elif dt.contains(QString('Dec')):
			dt.replace(QString('Dec'), self.locale.monthName(12))
		if dt.contains(QString('Mon')):
			dt.replace(QString('Mon'), self.locale.dayName(1))
		elif dt.contains(QString('Tue')):
			dt.replace(QString('Tue'), self.locale.dayName(2))
		elif dt.contains(QString('Wed')):
			dt.replace(QString('Wed'), self.locale.dayName(3))
		elif dt.contains(QString('Thu')):
			dt.replace(QString('Thu'), self.locale.dayName(4))
		elif dt.contains(QString('Fri')):
			dt.replace(QString('Fri'), self.locale.dayName(5))
		elif dt.contains(QString('Sat')):
			dt.replace(QString('Sat'), self.locale.dayName(6))
		elif dt.contains(QString('Sun')):
			dt.replace(QString('Sun'), self.locale.dayName(7))

	def startDocument(self):
		self.compareOnce = True
		self.read = 0
		self.start = False
		self.canAdd = False
		#self.read == 0 => nothing, 1=>link for compare new items, 2=>for save descriptions
		return True

	def endDocument(self):
		self.date = self.tempdate
		return True

	def startElement(self, uri, localName, qName, attr):
		if localName == 'item':
			self.start = True
			return True
		elif localName == 'description' and self.start is True:
			self.read = 2
			return True
		elif localName == 'pubDate' and self.start is True:
			self.read = 3
			return True
		else:
			self.read = 0
			return True

	def endElement(self, uri, localName, qName):
		self.read = 0
		if localName == 'item' and self.start is True:
			if self.canAdd is True:
				self.rss.addItem(self.temp)
				self.canAdd = False
			self.start = False
		return True

	def characters(self, ch):
		if self.read == 2 and ch != '\n':
			self.temp = []
			self.temp.append(ch.simplified())
			return True
		elif self.read == 3 and self.compareOnce is True:
			self.compareOnce = False
			dateTimeString = ch.simplified()
			self._translateDateTimeToLocal(dateTimeString)
			localDateTime = QDateTime.fromString(dateTimeString, QString("dddd, dd MMMM yyyy HH:mm:ss +0800"))
			self.temp.append(localDateTime.toLocalTime().toString("HH:mm:ss"))
			if self.date >= localDateTime:
				self.canAdd = False
				return False
			else:
				self.canAdd = True
				self.tempdate = localDateTime
				return True
		elif self.read == 3 and self.compareOnce is False:
			dateTimeString = ch.simplified()
			self._translateDateTimeToLocal(dateTimeString)
			localDateTime = QDateTime.fromString(dateTimeString, QString("dddd, dd MMMM yyyy HH:mm:ss +0800"))
			self.temp.append(localDateTime.toString("HH:mm:ss"))
			if self.date.__ge__(localDateTime):
				self.canAdd = False
				return True
			else:
				self.canAdd = True
				return True
		else:
			return True

class IngRss(QtCore.QObject):
	def __init__(self, url, nickname, proxy):
		QtCore.QObject.__init__(self)
		self.proxy = proxy
		self.usrName = nickname
		nickname = nickname.toUtf8()
		self.ingEveryoneUrl = url + "/feed/ing"
		self.ingUserUrl = self.ingEveryoneUrl + "/" + urllib.quote(nickname)
		self.ingFriendsUrl = self.ingEveryoneUrl + "/friends/" + urllib.quote(nickname)
		self.currentUsingUrl = self.ingFriendsUrl
		self.mode = 'friends'
		self.rss = QXmlSimpleReader()
		self.source = QXmlInputSource()
		self.contentHandler = DefaultHandler(self)
		self.rss.setContentHandler(self.contentHandler)
		self.errortimes = 0

	def parseNewItems(self):
		self.itemList = []
		hasError = False
		try:
			if self.proxy == '':
				data = urllib.urlopen(self.currentUsingUrl).read().decode('utf-8', 'replace')
			else:
				proxies = {'http': self.proxy}
				opener = urllib.FancyURLopener(proxies)
				data = opener.open(self.currentUsingUrl).read().decode('utf-8', 'replace')
			self.source.setData(data)
		except IOError:
			hasError = True
			if self.errortimes == 10:
				self.emit(QtCore.SIGNAL("parseNewItemsError"))
				self.errortimes = 0
			else:
				self.errortimes = self.errortimes + 1
		except:
			hasError = True
			if self.errortimes == 10:
				self.emit(QtCore.SIGNAL("parseNewItemsError"))
				self.errortimes = 0
			else:
				self.errortimes = self.errortimes + 1

		if hasError is False and self.errortimes > 0:
			self.errortimes = 0

		if self.rss.parse(self.source):
			self.itemList.reverse()
			if self.itemList == []:
				return False
			else:
				self._genItemDictList()
				return True
		else:
			return False

	def _genItemDictList(self):
		self.itemDictList = []
		x = QRegExp('(^<.* align="left" style="background-color: #FFF; padding: 2px; margin: 0px 5px 5px 0px; border: 1px solid #CCC;" />)?')
		xx = QRegExp('(&nbsp;.*&nbsp;)')
		if self.mode == 'me':
			xxx = QRegExp('(&nbsp;.*-)')
		else:
			xxx = QRegExp('(:&nbsp;.*-)')
		xxxx = QRegExp('(.*/)(p_)?(\\d+)(_n)(.[jpg|gif])(.*)')
		for i in self.itemList:
			t = {}
			x.indexIn(i[0])
			xxxx.indexIn(x.cap(0))
			t['userDisplayPicture'] = xxxx.cap(1) + xxxx.cap(2) + xxxx.cap(3) + '_s' + xxxx.cap(5) +xxxx.cap(6)
			if self.mode != 'me':
				xx.indexIn(i[0])
				t['userNickname'] = xx.cap(0)[6:-7]
			else:
				t['userNickname'] = QtCore.QString(self.usrName)
			xxx.indexIn(i[0])
			if self.mode == 'me':
				t['content'] = xxx.cap(0)[6:-2]
			else:
				t['content'] = xxx.cap(0)[7:-2]
			t['date'] = i[1]
			self.itemDictList.append(t)

	def getItems(self):
		return self.itemDictList

	def setCurrentUsingUrl(self, w):
		#w = 'me' -> me; w = 'friends' -> friends; w = 'everyone' -> everyone
		if w == 'me':
			self.currentUsingUrl = self.ingUserUrl
			self.mode = 'me'
		elif w == 'friends':
			self.currentUsingUrl = self.ingFriendsUrl
			self.mode = 'friends'
		else:
			self.currentUsingUrl = self.ingEveryoneUrl
			self.mode = 'everyone'

	def addItem(self, item):
		self.itemList.append(item)
		return True
